package controller

import (
	"encoding/json"
	"fmt"
	"github.com/afex/hystrix-go/hystrix"
	"github.com/afocus/captcha"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/gomodule/redigo/redis"
	"github.com/spf13/viper"
	"github.com/tedcy/fdfs_client"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"image/png"
	"myweb/web/auth/interceptor"
	"myweb/web/dao/mysql"
	"myweb/web/model"
	"myweb/web/proto/getCaptcha"
	"myweb/web/proto/user"
	"myweb/web/utils"
	"net/http"
	"path"
)

// 控制器接收请求数据，将数据分发给服务进行处理，再向客户端返回数据
// 处理用户相关的请求

// GetSession 获取用户会话
// @Summary 用户会话
// @Description 获取session信息服务
// @Tags 用户业务接口
// @Accept application/json
// @Produce application/json
// @Param object query string false "查询参数"
// @Success 200 {object} string "用户名"
// @Router /api/v1.0/session [GET]
func GetSession(ctx *gin.Context) {

	session := sessions.Default(ctx)
	userName := session.Get("userName")
	fmt.Println("------------------userName: ", userName)

	// 初始化错误返回的map
	resp := make(map[string]interface{})
	if userName.(string) == "" {
		resp["errno"] = utils.RECODE_SESSIONERR
		resp["errmsg"] = utils.RecodeText(utils.RECODE_SESSIONERR)

	} else {
		resp["errno"] = utils.RECODE_OK
		resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)

		//var nameData struct {
		//	Name string `json:"name"`
		//}
		//
		//nameData.Name = userName.(string)

		resp["data"] = gin.H{
			"name": userName.(string),
		}
	}

	ctx.JSON(http.StatusOK, resp)
}

// GetImageCd 获取图片验证码
// @Summary 图片验证码
// @Description 获取图片验证码
// @Tags 用户业务接口
// @Accept plain
// @Produce png
// @Param uuid path string true "路径变量参数"
// @Success 200 {object} string "验证码"
// @Router /api/v1.0/imagecode/:uuid [GET]
func GetImageCd(ctx *gin.Context) {

	/*
		// 获取图片验证码 uuid
		uuid := ctx.Param("uuid")
		// 指定consul服务发现
		consulReg := consul.NewRegistry()
		consulService := micro.NewService(micro.Registry(consulReg))

		// 调用函数
		microClient := getCaptcha.NewGetCaptchaService("getcaptcha", consulService.Client())

		// 调用远程函数
		resp, err := microClient.Call(context.TODO(), &getCaptcha.Request{})
		if err != nil {
			fmt.Println("未找到远程服务...")
			return
		}

		// 将得到的数据反序列化，得到图片数据
		var img captcha.Image
		json.Unmarshal(resp.Img, &img)
	*/

	// 获取请求路径中定义的变量
	uuid := ctx.Param("uuid")
	fmt.Println("uuid", uuid)
	// 生成图片
	//image, strCode := utils.CreateImage(4, captcha.NUM)

	//// 连接微服务==============================
	//// etcd地址
	//etcdAddr := conf.Conf.Etcd.Address
	//
	//// 服务名
	//getCaptchaServiceName := viper.GetString("service.GetCaptcha")
	//// 注册etcd解析器
	//etcdResolver := discovery.NewResolver([]string{etcdAddr}, logrus.New())
	//// grpc中注册ETCD服务发现解析器
	//resolver.Register(etcdResolver)
	//
	//// 连接时长上下文
	////ctx, _ := context.WithTimeout(context.Background(), 3*time.Second)
	//
	//// 连接 验证码微服务
	//getCaptchaConn, err := RPCConnect(ctx, getCaptchaServiceName, etcdResolver.Scheme(), insecure.NewCredentials())
	//if err != nil {
	//	fmt.Printf("服务:%v,RPCConnect连接建立失败,err:%v\n", getCaptchaServiceName, err)
	//}
	//fmt.Printf("服务:%v,RPCConnect连接建立完成\n", getCaptchaServiceName)
	////获得grpc句柄 生成GetCaptcha_service微服务操作客户端
	//captchaClient := getCaptcha.NewGetCaptchaClient(getCaptchaConn)

	captchaClient := ctx.Keys["GetCaptcha"].(getCaptcha.GetCaptchaClient)
	var resp = new(getCaptcha.Response)

	// 调用远程函数
	resp, err := captchaClient.Call(context.TODO(), &getCaptcha.Request{Uuid: uuid})
	if err != nil {
		fmt.Println("未找到远程服务..., err= ", err)
		return
	}
	// 解析微服务传来的数据 返回成image
	img := new(captcha.Image)
	err = json.Unmarshal(resp.Img, &img)
	if err != nil {
		fmt.Println("json.Unmarshal(resp.Img, &image)", err)
		return
	}
	/*
		// 改成微服务

		// 生成图片验证码

		//初始化对象
		cap := captcha.New()

		// 设置字体
		cap.SetFont("./conf/comic.ttf")
		// 设置验证码大小
		cap.SetSize(128, 64)
		// 设置干扰强度
		cap.SetDisturbance(captcha.NORMAL)
		// 设置前景色 可以多个 随机替换文字颜色 默认黑色
		cap.SetFrontColor(color.RGBA{255, 255, 255, 255})
		// 设置背景色 可以多个 随机替换背景色 默认白色
		cap.SetBkgColor(color.RGBA{255, 0, 0, 255}, color.RGBA{0, 0, 255, 255}, color.RGBA{0, 153, 0, 255})

		// 生成字体
		img, str := cap.Create(6, captcha.ALL)

	*/
	// 将图片写出到浏览器
	// ctx.Writer 是 Gin web 框架中的一个字段，它是一个 io.Writer，用于写入 HTTP 响应体。
	png.Encode(ctx.Writer, img)
	//fmt.Println("str = ", str)
	fmt.Println("uuid = ", uuid)
}

// GetSmscd 获取短信验证码接口
// @Summary 短信验证码
// @Description 获取短信验证码
// @Tags 用户业务接口
// @Accept plain
// @Produce json
// @Param phone path string true "路径变量参数"
// @Success 200 {string} string "消息"
// @Router /api/v1.0/smscode/:mobile [GET]

// http://10.10.53.170:8080/api/v1.0/smscode/15611327988?text=1439&id=b4dfa808-8294-4673-9bd4-15ab4da95c87

func GetSmsCd(ctx *gin.Context) {
	phone := ctx.Param("phone")
	// 2.拆分get请求中 的查询参数 uuid和text
	imgCode := ctx.Query("text") //图片验证码值
	uuid := ctx.Query("id")      //图片验证码的uuid

	fmt.Println("GetSmscd :", phone, imgCode, uuid)

	//// etcd地址
	//etcdAddr := conf.Conf.Etcd.Address
	//
	//// 服务名
	//userServiceName := viper.GetString("service.User")
	//
	//// 注册etcd解析器
	//etcdResolver := discovery.NewResolver([]string{etcdAddr}, logrus.New())
	//
	//// grpc中注册ETCD服务发现解析器
	//resolver.Register(etcdResolver)
	//
	//// 连接时长上下文
	////ctx, _ := context.WithTimeout(context.Background(), 3*time.Second)
	//
	//// 连接 验证码微服务
	//userServiceConn, err := RPCConnect(ctx, userServiceName, etcdResolver.Scheme(), insecure.NewCredentials())
	//if err != nil {
	//	fmt.Printf("服务:%v,RPCConnect连接建立失败,err:%v\n", userServiceName, err)
	//}
	//fmt.Printf("服务:%v,RPCConnect连接建立完成\n", userServiceName)
	////获得grpc句柄 生成GetCaptcha_service微服务操作客户端
	//userClient := user.NewUserClient(userServiceConn)

	userServiceName := ctx.Keys["User"].(user.UserClient)
	// 调用远程函数
	var resp = new(user.Response)
	err := hystrix.Do("user", func() error {
		var err error
		resp, err = userServiceName.SendSms(context.TODO(), &user.Request{Mobile: phone, ImgCode: imgCode, ImgUuid: uuid})
		return err
	}, nil)

	if err != nil {
		fmt.Printf("未找到远程服务%s, err:%v\n", userServiceName, err)
		return
	}

	// 发送校验结果给 浏览器
	// 将 resp 转换为 JSON 格式，并以 HTTP 状态码 200 的形式发送给客户端。
	ctx.JSON(http.StatusOK, resp)
}

func RPCConnect(ctx context.Context, serviceName string, scheme string, credentials credentials.TransportCredentials) (conn *grpc.ClientConn, err error) {
	// 不能加author
	addr := fmt.Sprintf("%s:///%s", scheme, serviceName)

	/*
		    建立grpc连接
		    grpc.WithDefaultServiceConfig({"loadBalancingPolicy": "round_robin"}): 此选项将默认服务配置设置为使用轮循负载均衡策略。这意味着请求将在服务的所有可用实例中均匀分布。
			grpc.WithTransportCredentials(credentials): 此选项设置要用于连接的传输凭据。这些凭证用于对客户机和服务器进行身份验证，反之亦然，并用于加密通过连接发送的数据。
	*/
	conn, err = grpc.DialContext(ctx, addr, grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`), grpc.WithTransportCredentials(credentials),
		grpc.WithPerRPCCredentials(&interceptor.Authentication{
			User: "admin",
			Pwd:  "admin",
		}))

	return
}

// PostRet 提交用户注册请求
// @Summary 提交用户注册请求
// @Description 提交用户注册请求
// @Tags 用户业务接口
// @Accept json
// @Produce json
// @Param mobile body string true "手机号"
// @Param password body string true "密码"
// @Param sms_code body string true "验证码"
// @Success 200 {string} string "消息"
// @Router /api/v1.0/users [POST]
func PostRet(ctx *gin.Context) {

	var regData struct {
		Mobile   string `json:"mobile"`
		PassWord string `json:"password"`
		SmsCode  string `json:"sms_code"`
	}

	ctx.Bind(&regData)
	fmt.Println("获取到的数据： ", regData)

	//// etcd地址
	//etcdAddr := conf.Conf.Etcd.Address
	//// 服务名
	//userServiceName := viper.GetString("service.User")
	//// 注册etcd解析器
	//etcdResolver := discovery.NewResolver([]string{etcdAddr}, logrus.New())
	//// grpc中注册ETCD服务发现解析器
	//resolver.Register(etcdResolver)
	//
	//// 连接时长上下文
	////ctx, _ := context.WithTimeout(context.Background(), 3*time.Second)
	//
	//// 连接用户微服务
	//userServiceConn, err := RPCConnect(ctx, userServiceName, etcdResolver.Scheme(), insecure.NewCredentials())
	//if err != nil {
	//	fmt.Printf("服务:%v,RPCConnect连接建立失败,err:%v\n", userServiceName, err)
	//}
	//fmt.Printf("服务:%v,RPCConnect连接建立完成\n", userServiceName)
	////获得grpc句柄 生成userClient微服务操作客户端
	//userClient := user.NewUserClient(userServiceConn)

	userServiceName := ctx.Keys["User"].(user.UserClient)

	// 调用远程函数
	var resp = new(user.Response)
	err := hystrix.Do("user", func() error {
		var err error
		resp, err = userServiceName.Register(context.TODO(), &user.RegReq{Mobile: regData.Mobile, Password: regData.PassWord, SmsCode: regData.SmsCode})
		return err
	}, nil)

	if err != nil {
		fmt.Printf("未找到远程服务%s, err:%v\n", userServiceName, err)
		return
	}

	// 发送校验结果给 浏览器
	// 将 resp 转换为 JSON 格式，并以 HTTP 状态码 200 的形式发送给客户端。
	ctx.JSON(http.StatusOK, resp)
}

func GetArea(ctx *gin.Context) {

	var areas []model.Area

	//从缓存redis中获取数据
	redisConn := model.RedisPool.Get()
	defer redisConn.Close()

	// 用 字节切片存入，再用切片类型接收
	bytes, err := redis.Bytes(redisConn.Do("get", "areaData"))
	if err != nil || len(bytes) == 0 {
		fmt.Println("从MySql中获取数据....")
		// 先从MySql中获取数据
		mysql.GormDB.Find(&areas)
		// 再把数据写入redis中，存储结构体序列化后的json串
		bytes, err = json.Marshal(areas)
		if err != nil {
			fmt.Println("json.Marshal(areas) err:", err)
		}
		redisConn.Do("set", "areaData", bytes)
	} else {
		fmt.Println("从redis获取数据...")
		json.Unmarshal(bytes, &areas)
	}

	resp := make(map[string]interface{})
	resp["errno"] = utils.RECODE_OK
	resp["errms"] = utils.RecodeText(utils.RECODE_OK)
	resp["data"] = areas

	ctx.JSON(http.StatusOK, resp)
}

// PostLogin 用户登录路由
// @Summary 用户登录
// @Description 用户登录
// @Tags 用户业务接口
// @Accept json
// @Produce json
// @Param mobile body string true "手机号"
// @Param password body string true "密码"
// @Success 200 {string} string "消息"
// @Router /api/v1.0/sessions [POST]
func PostLogin(ctx *gin.Context) {
	// 获取前端数据
	var loginData struct {
		Mobile   string `json:"mobile""`
		PassWord string `json:"password""`
	}

	err := ctx.Bind(&loginData)
	if err != nil {
		fmt.Println("err:", err)
		ResponseError(ctx, utils.RECODE_LOGINERR)
		return
	}
	fmt.Println("reqData ", loginData)

	//// etcd地址
	//etcdAddr := conf.Conf.Etcd.Address
	//// 服务名
	//userServiceName := viper.GetString("service.User")
	//// 注册etcd解析器
	//etcdResolver := discovery.NewResolver([]string{etcdAddr}, logrus.New())
	//// grpc中注册ETCD服务发现解析器
	//resolver.Register(etcdResolver)
	//
	//// 连接时长上下文
	////ctx, _ := context.WithTimeout(context.Background(), 3*time.Second)
	//
	//// 连接用户微服务
	//userServiceConn, err := RPCConnect(ctx, userServiceName, etcdResolver.Scheme(), insecure.NewCredentials())
	//if err != nil {
	//	fmt.Printf("服务:%v,RPCConnect连接建立失败,err:%v\n", userServiceName, err)
	//}
	//fmt.Printf("服务:%v,RPCConnect连接建立完成\n", userServiceName)
	////获得grpc句柄 生成userClient微服务操作客户端
	//userClient := user.NewUserClient(userServiceConn)

	userServiceName, ok := ctx.Keys["User"].(user.UserClient)
	if !ok {
		fmt.Printf("未找到远程服务%s, err:%v\n", userServiceName, err)
		return
	}

	// 调用远程函数
	var resp = new(user.Response)
	err = hystrix.Do("user", func() error {
		var err error
		resp, err = userServiceName.Login(ctx, &user.RegReq{Mobile: loginData.Mobile, Password: loginData.PassWord})
		return err
	}, nil)

	if err != nil {
		fmt.Printf("未找到远程服务%s, err:%v\n", userServiceName, err)
		return
	}

	// 将登陆状态，保存到Session中
	nowName, _ := mysql.GetUserName(loginData.Mobile)
	println("---------------从mysql登陆名： ", nowName)
	saveSession(ctx, "userName", nowName)

	// 发送校验结果给 浏览器
	// 将 resp 转换为 JSON 格式，并以 HTTP 状态码 200 的形式发送给客户端。
	ctx.JSON(http.StatusOK, resp)

	//resp := make(map[string]interface{})
	//// 获取数据库数据，查询是否和数据的数据匹配
	//res, _ := mysql.CheckUserNameAndPWD(loginData.Mobile, loginData.PassWord)
	//if res == false {
	//	fmt.Println("用户名或密码错误")
	//	resp["errno"] = utils.RECODE_LOGINERR
	//	resp["errmsg"] = utils.RecodeText(utils.RECODE_LOGINERR)
	//} else {
	//	resp["errno"] = utils.RECODE_OK
	//	resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)
	//
	//	// 将登陆状态，保存到Session中
	//	session := sessions.Default(ctx) // 调用session, 设置session数据
	//	nowName, _ := mysql.GetUserName(loginData.Mobile)
	//	println("从mysql登陆名： ", nowName)
	//	session.Set("userName", nowName)
	//	session.Save()
	//}
	//
	//ctx.JSON(http.StatusOK, resp)
}

// DeleteSession 退出登录状态
// @Summary 退出登录状态
// @Description 退出登录状态
// @Tags 用户业务接口
// @Produce application/json
// @Param object formData string false "查询参数"
// @Success 200 {string} string "消息"
// @Router /api/v1.0/session [DELETE]
func DeleteSession(ctx *gin.Context) {

	var resp = make(map[string]interface{})

	session := sessions.Default(ctx)
	session.Delete("userName")
	err := session.Save()
	if err != nil {
		fmt.Println("用户状态删除失败!")
		resp["errno"] = utils.RECODE_SERVERERR
		resp["errmsg"] = utils.RecodeText(utils.RECODE_SERVERERR)
	} else {
		resp["errno"] = utils.RECODE_OK
		resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)
	}

	ctx.JSON(http.StatusOK, resp)
}

// GetUserInfoEx 获取用户信息
// @Summary 获取用户信息
// @Description 获取用户信息
// @Tags 用户业务接口
// @Accept json
// @Produce json
// @Param userName query string true "用户名"
// @Success 200 {string} model.User "用户信息"
// @Router /api/v1.0/user [GET]
func GetUserInfo(ctx *gin.Context) {

	// 获取session, 得到当前用户信息
	session := sessions.Default(ctx)
	userName := session.Get("userName")
	fmt.Println("userName", userName.(string))
	// 读取数据库的用户信息
	// 调用微服务 由mysql校验登录信息
	userService := ctx.Keys["User"].(user.UserClient)

	var userInfoResp = new(user.GetUserInfoResp)
	err := hystrix.Do("user", func() error {
		var err error
		userInfoResp, err = userService.GetUserInfo(ctx, &user.GetUserInfoReq{
			Name: userName.(string),
		})
		return err
	}, nil)

	if err != nil {
		fmt.Println("用户查询失败1")
		ResponseError(ctx, utils.RECODE_SERVERERR)
		return
	}
	if userInfoResp.Errno == utils.RECODE_USERERR {
		fmt.Println("用户查询失败2")
		ResponseError(ctx, utils.RECODE_USERERR)
		return
	}
	if userInfoResp.Errno == utils.RECODE_DATAERR {
		fmt.Println("用户序列化失败")
		ResponseError(ctx, utils.RECODE_DATAERR)
		return
	}
	var user model.User
	err = json.Unmarshal([]byte(userInfoResp.User), &user)
	if err != nil {
		fmt.Println("用户反序列化失败")
		ResponseError(ctx, utils.RECODE_DATAERR)
		return
	}

	fmt.Println("userinfo : ", user)

	ResponseOK(ctx, utils.RECODE_OK, user)
}

func GetUserInfoEx(ctx *gin.Context) {

	resp := make(map[string]interface{})
	defer ctx.JSON(http.StatusOK, resp)

	// 获取session, 得到当前用户信息
	s := sessions.Default(ctx)
	userName := s.Get("userName")

	// 判断用户名是否存在
	if userName == nil {
		resp["errno"] = utils.RECODE_SESSIONERR
		resp["errmsg"] = utils.RecodeText(utils.RECODE_SESSIONERR)
		return
	}

	// 根据用户名获取用户信息 查询mysql
	user, err := mysql.GetUserInfo(userName.(string))
	if err != nil {
		resp["errno"] = utils.RECODE_DBERR
		resp["errmsg"] = utils.RecodeText(utils.RECODE_DBERR)
		return
	}

	resp["errno"] = utils.RECODE_OK
	resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)

	temp := make(map[string]interface{})
	temp["user_id"] = user.ID
	temp["name"] = user.Name
	temp["mobile"] = user.Mobile
	temp["real_name"] = user.Real_name
	temp["id_card"] = user.Id_card
	temp["avatar_url"] = user.Avatar_url

	resp["data"] = temp
}

// PutUserInfo 修改用户名提交
// @Summary 修改用户名提交
// @Description 修改用户名提交
// @Tags 修改用户名提交
// @Accept json
// @Produce json
// @Param name body string true "用户名"
// @Success 200 {string} nameData "用户信息"
// @Router /api/v1.0/user/name [PUT]
func PutUserInfo(ctx *gin.Context) {
	// 获取当前用户名
	s := sessions.Default(ctx)
	oldName := s.Get("userName")

	// 获取新用户名
	var newName struct {
		Name string `json:"name"`
	}
	ctx.Bind(&newName)

	// 更新用户名
	resp := make(map[string]interface{})
	defer ctx.JSON(http.StatusOK, resp)
	fmt.Printf("session old name:%s, update new name: %s,\n", oldName, newName.Name)

	err := mysql.UpdateUserName(oldName.(string), newName.Name)
	if err != nil {
		resp["errno"] = utils.RECODE_DBERR
		resp["errmsg"] = utils.RecodeText(utils.RECODE_DBERR)
		return
	}

	s.Set("userName", newName.Name)
	err = s.Save()
	if err != nil {
		resp["errno"] = utils.RECODE_SESSIONERR
		resp["errmsg"] = utils.RecodeText(utils.RECODE_SESSIONERR)
		return
	}

	resp["errno"] = utils.RECODE_OK
	resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)
	resp["data"] = newName
}

// PostAvatar 上传用户头像
// @Summary 上传用户头像
// @Description 上传用户头像
// @Tags 上传用户头像
// @Accept mpfd
// @Produce json
// @Param avatar formData file true "用户名"
// @Success 200 {string} nameData "信息"
// @Router /api/v1.0/user/avatar [POST]
func PostAvatar(ctx *gin.Context) {
	// 获取图片文件，静态文件对象
	file, _ := ctx.FormFile("avatar")

	// 上传文件到指定的路径
	//err := ctx.SaveUploadedFile(file, "./test/"+file.Filename)
	//if err != nil {
	//	fmt.Println("savauploadfile failed: ", err)
	//}

	// 上传头像到fastdfs中
	cli, _ := fdfs_client.NewClientWithConfig("/home/uos/go/src/myweb/web/conf/fdfs.conf")

	// 打开文件，读取文件内容
	f, _ := file.Open()

	buf := make([]byte, file.Size)
	// 读取文件内容，保存至缓冲区
	f.Read(buf)

	// go语言根据文件名获取文件后缀, 带有"."
	fileExt := path.Ext(file.Filename)

	// 按字节流上传图片内容
	remoteID, _ := cli.UploadByBuffer(buf, fileExt[1:])
	fmt.Println("remoteId:= ", remoteID)

	// 获取session, 得到当前用户
	userName := sessions.Default(ctx).Get("userName")
	fmt.Println("------------获取seesion,得到当前用户 userName:= ", userName)
	// 根据用户名，更新用户图像
	mysql.UpdateAvatar(userName.(string), remoteID)

	resp := make(map[string]interface{})
	resp["errno"] = utils.RECODE_OK
	resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)

	temp := make(map[string]interface{})
	temp["avatar_url"] = "http://" + viper.GetString("server.localAddress") + "/" + remoteID
	resp["data"] = temp

	ctx.JSON(http.StatusOK, resp)

	/*
		{
		    "errno": "0",
		    "errmsg": "成功",
		    "data": {
		        "user_id": 0,
		        "name": "pink",
		        "mobile": "18518980212",
		        "real_name": "caoxiansheng",
		        "id_card": "1111111111111111",
		        "avatar_url": "http://10.10.53.170:80/group1/M00/00/00/Cgo1qmUIG_WAKJiXAFEtSs1PAl4877.jpg",
		        "Houses": null,
		        "Orders": null
		    }
		}
	*/
}

// PostUserAuth 用户实名认证
// @Summary 用户实名认证
// @Description 用户实名认证
// @Tags 用户实名认证
// @Accept json
// @Produce json
// @Param real_name body string true "真实姓名"
// @Param id_card body string true "身份证"
// @Success 200 {string} string "信息"
// @Router /api/v1.0/user/auth [POST]
func PostUserAuth(ctx *gin.Context) {
	var authInfo struct {
		RealName string `json:"real_name""`
		IDCard   string `json:"id_card"`
	}

	err := ctx.ShouldBind(&authInfo)
	if err != nil {
		fmt.Println("err:", err)
		ResponseError(ctx, utils.RECODE_REQERR)
		return
	}
	fmt.Println("authinfo: ", authInfo)

	// 获取session
	session := sessions.Default(ctx)
	userName := session.Get("userName")

	userServiceName, ok := ctx.Keys["User"].(user.UserClient)
	if !ok {
		fmt.Printf("未找到远程服务%s, err:%v\n", userServiceName, err)
		return
	}

	var rsp = new(user.Response)
	err = hystrix.Do("user", func() error {
		var err error
		rsp, err = userServiceName.SaveRealName(ctx, &user.SaveRealNameReq{
			Name:     userName.(string),
			RealName: authInfo.RealName,
			IdCard:   authInfo.IDCard,
		})
		return err
	}, nil)

	if err != nil {
		fmt.Println("系统调用微服务错误:", err)
		ResponseError(ctx, utils.RECODE_SERVERERR)
		return
	}
	if rsp.Errno == utils.RECODE_DBERR {
		fmt.Println("保存用户实名信息错误err:", err)
		ResponseError(ctx, utils.RECODE_SERVERERR)
		return
	}
	ResponseOK(ctx, utils.RECODE_OK, "用户真实信息保存成功")
}
